#include "../engine/core.h"
#include "GateMsgHandler.h"
#include "../engine/ComputureMgr.h"
#include "../engine/Protocal/Common.pb.h"
#include "../engine/AsioTcpLink.h"
#include "../engine/AsioTcpLinkClient.h"
#include "../engine/GlobalConfig.h"
#include "../engine/ServerCore.h"
#include "../engine/Misc.h"
#include "../engine/LogMgr.h"
#include "../engine/UserMgr.h"
#include "../engine/DbExecute.h"

IMP_SINGLETON_CLASS(CGateMsgHandler)

CGateMsgHandler::CGateMsgHandler()
{
	Reg();
}

CGateMsgHandler::~CGateMsgHandler()
{
	UnReg();
}

void CGateMsgHandler::UnReg()
{
	CPacketProcesser* processer = CPacketProcesser::getInstance();
	if (processer)
	{
		processer->UnRegDefaultCB();
		processer->UnReg(MYTH::CMD_User_Login_r);
		processer->UnReg(MYTH::CMD_User_Key);
		processer->UnReg(MYTH::CMD_Role_Login);
	}
}

void CGateMsgHandler::Reg()
{
	CPacketProcesser* processer = CPacketProcesser::getInstance();
	if (processer)
	{
		processer->RegDefaultCB(boost::BOOST_BIND(&CGateMsgHandler::OnDefault, this, _1));
		processer->RegCB(MYTH::CMD_User_Login_r, boost::BOOST_BIND(&CGateMsgHandler::OnUserLogin_r, this, _1));
		processer->RegCB(MYTH::CMD_User_Key, boost::BOOST_BIND(&CGateMsgHandler::OnUserKey, this, _1));
		processer->RegCB(MYTH::CMD_Role_Login, boost::BOOST_BIND(&CGateMsgHandler::OnRoleLogin, this, _1));
	}
}

void CGateMsgHandler::OnUserKey(xMSG& msg)
{
	net_obj_ptr pLink = xNetObjBase::getNetObj(msg.call_guid);
	if (pLink.get())
	{
		MYTH::User_Key k;
		if (k.ParseFromArray(msg.getParameterData(), msg.getParameterSize()))
		{
			CUserMgr* pMgr = CUserMgr::getInstance();
			CUser * pUser = pMgr->getUser(k.account_id());
			if (!pUser)
			{
				pUser = pMgr->CreateUserByKey(k);
			}
			if (pUser)
			{
				std::string key = pUser->user.key();
				if (key.size())
				{
					if (key == k.key())
					{
						pUser->setBindGuid(pLink->getGuid());
						pLink->setBindGuid(pUser->getGuid());
						pUser->SendKeyRCmd();
					}
				}
				else
				{
					pUser->setBindGuid(pLink->getGuid());
					pLink->setBindGuid(pUser->getGuid());
					pUser->user.set_key(k.key());
				}
			}
		}
	}
}

void CGateMsgHandler::OnRoleLogin(xMSG& msg)
{
	net_obj_ptr pLink = xNetObjBase::getNetObj(msg.call_guid);
	if (pLink.get())
	{
		MYTH::Role_Login rl;
		if (rl.ParseFromArray(msg.getParameterData(), msg.getParameterSize()))
		{
			CUser* pUser = dynamic_cast<CUser*>(xObjBase::getObj(pLink->getBindGuid()));
			if (pUser)
			{
				if (pUser->user.account_id() == rl.account_id())
				{
					if (pUser->HaveRole(rl.role_id()))
					{
						CServerCore* core = CServerCore::getInstance();
						core->SendMsg2Server(ENetDef::NET_GAME_DB, msg);
					}
				}
			}
		}
	}
}

void CGateMsgHandler::OnUserLogin_r(xMSG& msg)
{
	CUserMgr* pMgr = CUserMgr::getInstance();
	MYTH::AccountLogin_R r;
	if (r.ParseFromArray(msg.getParameterData(), msg.getParameterSize()))
	{
		pMgr->GateOnLoginR(r);
	}
}

void CGateMsgHandler::OnDefault(xMSG& msg)
{
	net_obj_ptr pLink = xNetObjBase::getNetObj(msg.call_guid);
	if (pLink.get())
	{
		CUser* pUser = dynamic_cast<CUser*>(xObjBase::getObj(pLink->getBindGuid()));
		if (pUser)
		{
			U64 magic_id = pUser->getm_uMagicID();
			CServerCore* core = CServerCore::getInstance();
			core->SendMsg2Net(magic_id, msg);
		}
	}
}